from unit_test.base_test_case import BaseTestCase
from src.evaluate import BLEU, METEOR, TER, ChrF, COMET


class TestBLEU(BaseTestCase):
    def test_bleu_perfect_match(self):
        ref = "the cat is on the mat".split()
        hyp = "the cat is on the mat".split()
        self.assertScoreRange(BLEU().compute(ref, hyp), 1.0, 1.0)

    def test_bleu_partial_match(self):
        ref = "the cat is on the mat".split()
        hyp = "the cat is on mat".split()
        self.assertScoreRange(BLEU().compute(ref, hyp), 0.0, 1.0)

    def test_bleu_empty_hypothesis(self):
        ref = "the cat is on the mat".split()
        hyp = "".split()
        self.assertEqual(BLEU().compute(ref, hyp), 0.0)


class TestMETEOR(BaseTestCase):
    def test_meteor_perfect_match(self):
        ref = "the cat is on the mat".split()
        hyp = "the cat is on the mat".split()
        self.assertScoreRange(METEOR().compute(ref, hyp), 1.0, 1.0)

    def test_meteor_partial_match(self):
        ref = "the cat is on the mat".split()
        hyp = "the cat is on mat".split()
        score = METEOR().compute(ref, hyp)
        self.assertScoreRange(score, 0.0, 1.0)

    def test_meteor_empty_hypothesis(self):
        ref = "the cat is on the mat".split()
        hyp = "".split()
        self.assertEqual(METEOR().compute(ref, hyp), 0.0)


class TestTER(BaseTestCase):
    def test_perfect_match(self):
        ref = "the cat is on the mat".split()
        hyp = "the cat is on the mat".split()
        self.assertScoreRange(TER().compute(ref, hyp), 0.0, 0.0)

    def test_ter_partial_match(self):
        ref = "the cat is on the mat".split()
        hyp = "the cat is on mat".split()
        self.assertScoreRange(TER().compute(ref, hyp), 0.0, 1.0)

    def test_ter_empty_hypothesis(self):
        ref = "the cat is on the mat".split()
        hyp = "".split()
        self.assertScoreRange(TER().compute(ref, hyp), 1.0, 1.0)


class TestChrF(BaseTestCase):
    def test_chrf_perfect_match(self):
        ref = "the cat is on the mat".split()
        hyp = "the cat is on the mat".split()
        self.assertAlmostEqual(ChrF().compute(ref, hyp), 1.0, places=4)

    def test_chrf_partial_match(self):
        ref = "the cat is on the mat".split()
        hyp = "the cat is on mat".split()
        self.assertScoreRange(ChrF().compute(ref, hyp), 0.0, 1.0)

    def test_chrf_empty_hypothesis(self):
        ref = "the cat is on the mat".split()
        hyp = "".split()
        self.assertScoreRange(ChrF().compute(ref, hyp), 0.0, 0.0)


class TestCOMET(BaseTestCase):
    def test_comet_perfect_match(self):
        ref = "the cat is on the mat".split()
        hyp = "the cat is on the mat".split()
        self.assertAlmostEqual(COMET().compute(ref, hyp), 1.0, places=4)

    def test_comet_partial_match(self):
        ref = "the cat is on the mat".split()
        hyp = "the cat is on mat".split()
        score = COMET().compute(ref, hyp)
        self.assertScoreRange(score, 0.5, 1.0)

    def test_comet_empty_hypothesis(self):
        ref = "the cat is on the mat".split()
        hyp = "".split()
        self.assertScoreRange(COMET().compute(ref, hyp), 0.0, 0.0)

    def test_comet_case_insensitive(self):
        ref = "The Cat is On The Mat".split()
        hyp = "the cat is on the mat".split()
        self.assertAlmostEqual(COMET().compute(ref, hyp), 1.0, places=4)
